/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

import ChatLogic.User;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
//import com.explodingpixels.macwidgets.IAppWidgetFactory;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.StyledDocument;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

/**
 *
 * @author BjørnTore
 */
public class ChatMainFrame extends javax.swing.JFrame implements PropertyChangeListener {

    private PropertyChangeSupport chatMainFramePCS;
    private CopyOnWriteArrayList<UserPanel> userPanels = new CopyOnWriteArrayList<>();
    private boolean firstWrite = true;

    /**
     * Creates new form ChatMainFrame
     */
    public ChatMainFrame() {
        chatMainFramePCS = new PropertyChangeSupport(this);
        initComponents();
        jPanel2.setLayout(new GridLayout(10, 1, 0, 2));
        DefaultCaret caret = (DefaultCaret) jTextPane1.getCaret();
        jTextPane1.setContentType("text/html");
        jTextPane1.setEditorKit(kit);
        jTextPane1.setDocument(doc);
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
    }

    public void refreshUserList(CopyOnWriteArrayList<User> refreshedListOfUsers) {
        //Add UserPanel for new users
        boolean somethingChanged = false;
        for (User user : refreshedListOfUsers) {
            boolean wasFound = false;
            for (UserPanel userPanel : userPanels) {
                if (userPanel.getUser().getName().equalsIgnoreCase(user.getName())) {
                    wasFound = true;
                }
            }
            if (!wasFound) {
                jPanel2.add(new UserPanel(user));
                userPanels.add(new UserPanel(user));
                somethingChanged = true;
            }
        }

        //Remove UserPanels for disconnected users
        for (UserPanel userPanel : userPanels) {
            boolean wasFound = false;
            for (User user : refreshedListOfUsers) {
                if (user.getName().equalsIgnoreCase(userPanel.getUser().getName())) {
                    wasFound = true;
                }
            }
            if (!wasFound) {
                for (int i = 0; i < userPanels.size(); i++) {
                    try {
                        if (((UserPanel) jPanel2.getComponent(i)).getUser().getName().equalsIgnoreCase(userPanel.getUser().getName())) {
                            jPanel2.remove(i);
                            userPanels.remove(userPanel);
                            userPanel = null;
                            somethingChanged = true;
                        }
                    } catch (NullPointerException ex) {
                        System.out.println("nullPointer i GUI refreshListOfUsers remove user");
                        somethingChanged = true;
                    }
                }
            }
        }
        if (somethingChanged) {
            if (userPanels.size() != refreshedListOfUsers.size()) {
                jPanel2.removeAll();
                refreshUserList(refreshedListOfUsers);
            }
            jPanel2.validate();
            jPanel2.repaint();
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jScrollPane3.getVerticalScrollBar().setUnitIncrement(13);
        jTextPane1 = new javax.swing.JTextPane();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        //IAppWidgetFactory.makeIAppScrollPane(jScrollPane2);
        jScrollPane2.getVerticalScrollBar().setUnitIncrement(13);
        jPanel2 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("ChatClient");
        setForeground(java.awt.Color.black);
        setMinimumSize(new java.awt.Dimension(400, 200));

        jPanel1.setMinimumSize(new java.awt.Dimension(390, 160));

        jScrollPane3.setBorder(null);

        jTextPane1.setEditable(false);
        jTextPane1.setBackground(new java.awt.Color(242, 237, 237));
        jTextPane1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(230, 230, 230)));
        jScrollPane3.setViewportView(jTextPane1);

        jTextField1.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N
        jTextField1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(233, 231, 231)));
        jTextField1.setNextFocusableComponent(jButton1);
        jTextField1.setPreferredSize(new java.awt.Dimension(59, 16));
        jTextField1.setSelectionColor(new java.awt.Color(204, 204, 204));
        jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextField1KeyPressed(evt);
            }
        });

        jButton1.setText("Send");
        jButton1.setFocusable(false);
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jButton1MouseReleased(evt);
            }
        });

        jScrollPane2.setBackground(new java.awt.Color(244, 244, 244));
        jScrollPane2.setBorder(null);
        jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane2.setViewportBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jScrollPane2.setAutoscrolls(true);
        jScrollPane2.setHorizontalScrollBar(null);
        jScrollPane2.setMinimumSize(new java.awt.Dimension(50, 22));
        jScrollPane2.setPreferredSize(new java.awt.Dimension(198, 439));

        jPanel2.setAutoscrolls(true);
        jPanel2.setMaximumSize(new java.awt.Dimension(200, 200));
        jPanel2.setMinimumSize(new java.awt.Dimension(50, 20));
        jPanel2.setPreferredSize(new java.awt.Dimension(292, 432));

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 292, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 437, Short.MAX_VALUE)
        );

        jScrollPane2.setViewportView(jPanel2);

        jButton2.setFont(new java.awt.Font("Segoe UI", 0, 12)); // NOI18N
        jButton2.setForeground(new java.awt.Color(255, 51, 51));
        jButton2.setToolTipText("Conversations");
        jButton2.setBorder(null);
        jButton2.setBorderPainted(false);
        jButton2.setContentAreaFilled(false);
        jButton2.setFocusable(false);
        jButton2.setName("conversationsButton"); // NOI18N
        jButton2.setRequestFocusEnabled(false);
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton2)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 785, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jScrollPane3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 194, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 71, Short.MAX_VALUE))
                    .addComponent(jScrollPane3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    public void writeOutput(String output, User user, int outputType) {


        if (user == null) {
            user = new User("Client");
        }

        try {
            System.out.println(jTextPane1.getText());
            if (!output.trim().equals("")) {
                if (firstWrite) {
                    //jTextPane1.setText(getTimeStamp() + user.getName() + ":</bold>  " + output);
                    kit.insertHTML(doc, doc.getLength(), "<p color='#0000FF'> " + getTimeStamp() + user.getName() + ":  " + output, 1, 0, HTML.Tag.P);
                    firstWrite = false;
                } else {
                    kit.insertHTML(doc, doc.getLength(), "<p> " + getTimeStamp() + user.getName() + ":  " + output, 1, 0, HTML.Tag.P);
                }
            }
        } catch (BadLocationException ex) {
            Logger.getLogger(ChatMainFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ChatMainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    

    private String getTimeStamp() {
        String hours;
        String minutes;
        if (Calendar.getInstance().getTime().getHours() < 10) {
            hours = "0" + Calendar.getInstance().getTime().getHours();
        } else {
            hours = "" + Calendar.getInstance().getTime().getHours();
        }
        if (Calendar.getInstance().getTime().getMinutes() < 10) {
            minutes = "0" + Calendar.getInstance().getTime().getMinutes();
        } else {
            minutes = "" + Calendar.getInstance().getTime().getMinutes();
        }
        return "  [" + hours + ":" + minutes + "]  ";
    }

    private void sendMessage(String signal, String messageText, String chatroomOrUser) {
        switch (signal) {
            case "SEND_TO_SERVER":
                chatMainFramePCS.firePropertyChange("SEND_TO_SERVER", chatroomOrUser, messageText);
                break;
        }
    }

    private void jButton1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseReleased
        sendMessage("SEND_TO_SERVER", jTextField1.getText(), "DEFAULT");
        jTextField1.setText("");
    }//GEN-LAST:event_jButton1MouseReleased

    private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            sendMessage("SEND_TO_SERVER", jTextField1.getText(), "DEFAULT");
            jTextField1.setText("");
        }
    }//GEN-LAST:event_jTextField1KeyPressed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jButton2ActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextPane jTextPane1;
    // End of variables declaration//GEN-END:variables
    HTMLEditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = new HTMLDocument();

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
    }

    public void addPropertyChangeListener(PropertyChangeListener PCL) {
        chatMainFramePCS.addPropertyChangeListener(PCL);
    }
}
